package com.plian.system.controller.zcgl;

import cn.hutool.core.util.DesensitizedUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.annotation.LogOperation;
import com.plian.system.common.status.CustomCode;
import com.plian.system.config.Resubmit;
import com.plian.system.dto.zcgl.ZcglStaffManagementDTO;
import com.plian.system.entity.hr.staff.Director;
import com.plian.system.entity.hr.staff.Supervisor;
import com.plian.system.entity.zcgl.ZcglStaffManagement;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.model.R;
import com.plian.system.mybatis.search.SearchEntity;
import com.plian.system.mybatis.search.SearchParamEntiy;
import com.plian.system.mybatis.search.TokenSearch;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.mybatis.support.Query;
import com.plian.system.service.hr.staff.IDirectorService;
import com.plian.system.service.hr.staff.ISupervisorService;
import com.plian.system.service.zcgl.IZcglStaffManagementService;
import com.plian.system.vo.report.ReportReturnVO;
import com.plian.system.vo.zcgl.ZcglStaffManagementVO;
import com.plian.system.wrapper.zcgl.ZcglStaffManagementWrapper;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.BaseConstant.BASE64_KEY;

/**
 * 经理人档案管理
 */
@RestController
@AllArgsConstructor
@RequestMapping("api/zcgl")
public class ZcglStaffManagementController {
    private IZcglStaffManagementService zcglStaffManagementService;

    private IDirectorService directorService;

    private ISupervisorService supervisorService;


    private ZcglStaffManagementWrapper staffFilesWrapper;

    /**
     * 详情
     */
    @PostMapping("/detail")
    public R<ZcglStaffManagementVO> detail(@Valid @RequestBody ZcglStaffManagement staffFiles) {
        ZcglStaffManagement one = zcglStaffManagementService.getOne(Condition.getQueryWrapper(staffFiles));
        ZcglStaffManagementVO staffFilesVO = staffFilesWrapper.entityToVO(one);
        if (one.getTermOfOffice() != null && !one.getTermOfOffice().isEmpty()){
            String[] split = one.getTermOfOffice().split("&");
            staffFilesVO.setTermOfOffices(Arrays.asList(split));
        }
        if (one.getOfficeHistory() != null && !one.getOfficeHistory().isEmpty()){
            staffFilesVO.setOfficeHistory(one.getOfficeHistory());
        }
        if (one.getOfficeType() != null && !one.getOfficeType().isEmpty()){
            staffFilesVO.setOfficeType(one.getOfficeType());
        }
        return zcglStaffManagementService.getDetailObj(staffFilesVO);
    }

    /**
     * 详情接口（数据脱敏）
     * @param staffFiles
     * @return
     */
    @PostMapping("/dataMaskingDetail")
    public R<ZcglStaffManagementVO> dataMaskingDetail(@Valid @RequestBody ZcglStaffManagement staffFiles) {
        R<ZcglStaffManagementVO> r = this.detail(staffFiles);
        // 脱敏处理
        if (r != null && r.getPageData() != null) {
            ZcglStaffManagementVO vo = r.getPageData();
            vo.setDocumentNumber(DesensitizedUtil.desensitized(vo.getDocumentNumber(), DesensitizedUtil.DesensitizedType.ID_CARD));
            vo.setPlaceOfDomicile(DesensitizedUtil.desensitized(vo.getPlaceOfDomicile(), DesensitizedUtil.DesensitizedType.ADDRESS));
            vo.setTelephone(DesensitizedUtil.desensitized(vo.getTelephone(), DesensitizedUtil.DesensitizedType.MOBILE_PHONE));
            vo.setEmail(DesensitizedUtil.desensitized(vo.getEmail(), DesensitizedUtil.DesensitizedType.EMAIL));
            vo.setWorkPhone(DesensitizedUtil.desensitized(vo.getWorkPhone(), DesensitizedUtil.DesensitizedType.FIXED_PHONE));
            vo.setFamilyAddress(DesensitizedUtil.desensitized(vo.getFamilyAddress(), DesensitizedUtil.DesensitizedType.ADDRESS));
            vo.setEmergencyContactUs(DesensitizedUtil.desensitized(vo.getEmergencyContactUs(), DesensitizedUtil.DesensitizedType.MOBILE_PHONE));
            r.setPageData(vo);
        }
        return r;
    }

    /**
     * 分页 员工档案
     */
    @PostMapping("/list")
    public ListResult<ZcglStaffManagementVO> list(@Valid @RequestBody Query query) {
        if (query.getAscs() == null && query.getDescs() == null) {
//            query.setAscs("order_number,department_code");
            query.setDescs("create_time,id");
        }

        List<SearchEntity> entityList = query.getSearch();
        QueryWrapper<ZcglStaffManagement> queryWrapper = SearchParamEntiy.getQueryWrapper(
                Condition.getQueryWrapper(new ZcglStaffManagement()), entityList
        );
//        queryWrapper.eq("create_company_id", TokenUtil.getTokenOrgId());
        TokenSearch<ZcglStaffManagement> tokenSearch = new TokenSearch<>();
        if(null == query.getFlag()) query.setFlag(1);
        tokenSearch.addTokenQuery(queryWrapper, query);

        queryWrapper.eq("is_out", 1);
        if (StringUtil.isNotBlank(query.getKeyword())) {
            queryWrapper.like("staff_name", query.getKeyword());
        }

        IPage<ZcglStaffManagement> pages = zcglStaffManagementService.page(Condition.getPage(query), queryWrapper);
        List<ZcglStaffManagementVO> staffFilesVOS = zcglStaffManagementService.setVO(pages.getRecords());
        ListResult<ZcglStaffManagementVO> listResult = new ListResult<>(CommonCode.SUCCESS);
        listResult.setList(staffFilesVOS);
        listResult.setTotal(Long.valueOf(pages.getTotal()).intValue());
        return listResult;
    }

    /**
     * 新增或修改 员工档案
     */
    @PostMapping("/submit")
    @Resubmit(delaySeconds = 0)
    @LogOperation("中层管理档案-提交")
    public R submit(@Valid @RequestBody ZcglStaffManagementVO staffFilesVO) {
        return zcglStaffManagementService.submit(staffFilesVO);
    }

    /**
     * 删除 员工档案
     */
    @PostMapping("/remove")
    @LogOperation("中层管理档案-删除")
    public R remove(@RequestBody PageData pd) {
        List<String> ids = (List<String>) pd.get("ids");
        return zcglStaffManagementService.deleteLogic(Func.toLongList(StringUtils.join(ids, StringPool.COMMA)))
                ? new R(CommonCode.SUCCESS) : new R(CommonCode.FAIL);
    }

    /**
     * 禁用 员工档案
     */
    @PostMapping("/disable")
    @LogOperation("中层管理档案-禁用")
    public R disable(@RequestBody PageData pd) {
        List<String> ids = (List<String>) pd.get("ids");
        return zcglStaffManagementService.disable(Func.toLongList(StringUtils.join(ids, StringPool.COMMA)))
                ? new R(CommonCode.SUCCESS) : new R(CommonCode.FAIL);
    }

    /**
     * 启用 员工档案
     */
    @PostMapping("/enable")
    @LogOperation("中层管理档案-启用")
    public R enable(@RequestBody PageData pd) {
        List<String> ids = (List<String>) pd.get("ids");
        return zcglStaffManagementService.enable(Func.toLongList(StringUtils.join(ids, StringPool.COMMA)))
                ? new R(CommonCode.SUCCESS) : new R(CommonCode.FAIL);
    }



    /**
     * @param staffFilesDTO
     * @return
     */
    @PostMapping("/report")
    public R<ReportReturnVO> reportTable(@RequestBody ZcglStaffManagementDTO staffFilesDTO) {
        ReportReturnVO reportReturnVO = zcglStaffManagementService.report(staffFilesDTO);
        R<ReportReturnVO> objResult = new R<>(CommonCode.SUCCESS);
        objResult.setPageData(reportReturnVO);
        return objResult;

    }

    @PostMapping("/reportChartsGender")
    public R<ReportReturnVO> reportChartsGender(@RequestParam(required = false) Long companyNameId) {
        return zcglStaffManagementService.getReportObj(zcglStaffManagementService.reportChartsGender(companyNameId));
    }

    @PostMapping("/reportChartsPoliticCountenance")
    public R<ReportReturnVO> reportChartsPoliticCountenance(@RequestParam(required = false) Long companyNameId) {
        return zcglStaffManagementService.getReportObj(zcglStaffManagementService.reportChartsPoliticCountenance(companyNameId));
    }

    @PostMapping("/reportChartsEducational")
    public R<ReportReturnVO> reportChartsEducational(@RequestParam(required = false) Long companyNameId) {
        return zcglStaffManagementService.getReportObj(zcglStaffManagementService.reportChartsEducational(companyNameId));
    }

    @PostMapping("/reportChartsWorkTime")
    public R<ReportReturnVO> reportChartsWorkTime(@RequestParam(required = false) Long companyNameId) {
        return zcglStaffManagementService.getReportObj(zcglStaffManagementService.reportChartsWorkTime(companyNameId));
    }

    /**
     * 打印
     */
    @GetMapping("/buildpdf/{id}")
//    @PassToken
    public ResponseEntity<FileSystemResource> buildPdf(@PathVariable Long id) {
        //return FileTools.exportPdf(zcglStaffManagementService.buildpdf(id));
        return FileTools.exportPdf(zcglStaffManagementService.createReceptFile(id));
    }

    /**
     * 新增导入(导入时仅导入系统内编码不存在的数据)
     */
    @PostMapping("/excelImport")
    @LogOperation("中层管理档案-导入")
    public ObjResult excelImport(@RequestParam("file") MultipartFile multipartFile) throws IOException {
        String progressId = TokenUtil.getTokenUserId() + "_" + System.currentTimeMillis();
        CacheUtil.put("progress", "progress", progressId + "#half:hour", 0);
        InputStream inputStream = multipartFile.getInputStream();
        zcglStaffManagementService.importExcel(progressId, inputStream, false);
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        PageData pd = new PageData();
        pd.put("progressId", progressId);
        objResult.setPageData(pd);
        return objResult;
    }

    /**
     * 覆盖导入(导入时仅导入系统内编码存在的数据)
     */
    @PostMapping("/excelCoverImport")
    @LogOperation("中层管理档案-导入")
    public ObjResult excelCoverImport(@RequestParam("file") MultipartFile multipartFile) throws IOException {
        String progressId = TokenUtil.getTokenUserId() + "_" + System.currentTimeMillis();
        CacheUtil.put("progress", "progress", progressId + "#half:hour", 0);
        InputStream inputStream = multipartFile.getInputStream();
        zcglStaffManagementService.importExcel(progressId, inputStream, true);
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        PageData pd = new PageData();
        pd.put("progressId", progressId);
        objResult.setPageData(pd);
        return objResult;
    }

    /**
     * 导入进度查看
     */
    @GetMapping("/progress/{progressId}")
    public ObjResult progress(@PathVariable String progressId) {
        Object data = CacheUtil.get("progress", "progress", progressId + "#half:hour");
        if (data != null && data instanceof String) {
            if ("导入成功".equals(data)) {
                ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
                PageData pd = new PageData();
                pd.put("data", 200);
                objResult.setPageData(pd);
                return objResult;
            }
            return new ObjResult(CustomCode.builder().message((String) data).code(1000).success(false).build());
        }
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        PageData pd = new PageData();
        pd.put("data", data);
        objResult.setPageData(pd);
        return objResult;
    }

    /**
     * 根据id获取单一对象
     */
    @GetMapping("/getById")
    public R<ZcglStaffManagementVO> detail(@RequestParam Long id) {
        return R.data(staffFilesWrapper.entityToVO(zcglStaffManagementService.getById(id)));
    }


    /**
     * 分页 用于董事会添加按钮获取上游单据
     */
    @PostMapping("/getDirectorPreList")
    public ListResult<ZcglStaffManagementVO> getDirectorPreList(@Valid @RequestBody Query query) {
        QueryWrapper<ZcglStaffManagement> queryWrapper = new QueryWrapper<>();
        /**
         * 排除已经被使用的数据
         */
        LambdaQueryWrapper<Director> directorQueryWrapper = new LambdaQueryWrapper<>();
        directorQueryWrapper.eq(Director::getCompanyId, TokenUtil.getTokenOrgId());
        List<Director> directors = directorService.list(directorQueryWrapper);
        List<Long> ids = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(directors)) {
            ids.addAll(directors.stream().filter(director -> director.getStaffFilesId() != null && director.getIsOutDirector() == 1)
                    .map(Director::getStaffFilesId).collect(Collectors.toList()));

        }

        LambdaQueryWrapper<Supervisor> supervisorQueryWrapper = new LambdaQueryWrapper<>();
        supervisorQueryWrapper.eq(Supervisor::getCompanyId, TokenUtil.getTokenOrgId());
        List<Supervisor> supervisors = supervisorService.list(supervisorQueryWrapper);
        if (CollectionUtil.isNotEmpty(supervisors)) {
            ids.addAll(supervisors.stream().filter(supervisor -> supervisor.getStaffFilesId() != null && supervisor.getIsOutSupervisor() == 2)
                    .map(Supervisor::getStaffFilesId).collect(Collectors.toList()));
        }

        if (CollectionUtil.isNotEmpty(ids)) {
            queryWrapper.notIn("id", ids);
        }

        return zcglStaffManagementService.getPreList(query, queryWrapper);
    }

    /**
     * 分页 用于监事添加按钮获取上游单据
     */
    @PostMapping("/getSupervisorPreList")
    public ListResult<ZcglStaffManagementVO> getSupervisorPreList(@Valid @RequestBody Query query) {
        QueryWrapper<ZcglStaffManagement> queryWrapper = new QueryWrapper<>();

        /**
         * 排除已经被使用的数据
         */
        LambdaQueryWrapper<Director> directorQueryWrapper = new LambdaQueryWrapper<>();
        directorQueryWrapper.eq(Director::getCompanyId, TokenUtil.getTokenOrgId());
        List<Director> directors = directorService.list(directorQueryWrapper);
        List<Long> ids = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(directors)) {
            ids.addAll(directors.stream().filter(director -> director.getStaffFilesId() != null && director.getIsOutDirector() == 1)
                    .map(Director::getStaffFilesId).collect(Collectors.toList()));

        }

        LambdaQueryWrapper<Supervisor> supervisorQueryWrapper = new LambdaQueryWrapper<>();
        supervisorQueryWrapper.eq(Supervisor::getCompanyId, TokenUtil.getTokenOrgId());
        List<Supervisor> supervisors = supervisorService.list(supervisorQueryWrapper);
        if (CollectionUtil.isNotEmpty(supervisors)) {
            ids.addAll(supervisors.stream().filter(supervisor -> supervisor.getStaffFilesId() != null && supervisor.getIsOutSupervisor() == 2)
                    .map(Supervisor::getStaffFilesId).collect(Collectors.toList()));
        }

        if (CollectionUtil.isNotEmpty(ids)) {
            queryWrapper.notIn("id", ids);
        }

        return zcglStaffManagementService.getPreList(query, queryWrapper);

    }

    /**
     * 分页员工档案
     */
    @PostMapping("/getByCompanyId")
    public ListResult<ZcglStaffManagementVO> getByCompanyId(@Valid @RequestBody ZcglStaffManagement staffFiles) {
        LambdaQueryWrapper<ZcglStaffManagement> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ZcglStaffManagement::getCompanyNameId, staffFiles.getCompanyNameId());
        queryWrapper.eq(ZcglStaffManagement::getDef18, 1);
        queryWrapper.eq(ZcglStaffManagement::getIsOut, 1);

        List<ZcglStaffManagementVO> staffFilesVOS = zcglStaffManagementService.setVO(zcglStaffManagementService.list(queryWrapper));
        ListResult<ZcglStaffManagementVO> listResult = new ListResult<>(CommonCode.SUCCESS);
        listResult.setList(staffFilesVOS);
        listResult.setTotal(staffFilesVOS.size());
        return listResult;
    }

    /**
     * 查询员工的人事档案信息和补充信息
     *
     * @param staffFiles
     * @return
     */
    @PostMapping("/getBaseInfoByCompanyId")
    public ListResult<ZcglStaffManagementVO> getBaseInfoByCompanyId(@Valid @RequestBody ZcglStaffManagement staffFiles) {
        LambdaQueryWrapper<ZcglStaffManagement> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ZcglStaffManagement::getCompanyNameId, staffFiles.getCompanyNameId());
        queryWrapper.eq(ZcglStaffManagement::getDef18, 1);
        queryWrapper.eq(ZcglStaffManagement::getIsOut, 1);

        List<ZcglStaffManagementVO> staffFilesVOS = zcglStaffManagementService.getBaseInfoByCompanyId(zcglStaffManagementService.list(queryWrapper));
        ListResult<ZcglStaffManagementVO> listResult = new ListResult<>(CommonCode.SUCCESS);
        listResult.setList(staffFilesVOS);
        listResult.setTotal(staffFilesVOS.size());
        return listResult;
    }


    @GetMapping("/exportTemplateExcel")
//    @PassToken
    public void exportTemplateExcel(HttpServletResponse response, OutputStream os) {
        zcglStaffManagementService.exportTemplateExcel(response, os);
    }

    /**
     * 分页 获取所有已审批的员工档案列表，和登录用户无关
     */
    @PostMapping("/allList")
    public ListResult<ZcglStaffManagementVO> allList(@Valid @RequestBody Query query) {
        if (query.getAscs() == null && query.getDescs() == null) {
            query.setDescs("create_time");
        }

        List<SearchEntity> entityList = query.getSearch();
        QueryWrapper<ZcglStaffManagement> queryWrapper = SearchParamEntiy.getQueryWrapper(
                Condition.getQueryWrapper(new ZcglStaffManagement()), entityList
        );
        queryWrapper.eq("def18", 1);
        queryWrapper.eq("is_out", 1);
        IPage<ZcglStaffManagement> pages = zcglStaffManagementService.page(Condition.getPage(query), queryWrapper);
        List<ZcglStaffManagementVO> staffFilesVOS = zcglStaffManagementService.setVO(pages.getRecords());
        ListResult<ZcglStaffManagementVO> listResult = new ListResult<>(CommonCode.SUCCESS);
        listResult.setList(staffFilesVOS);
        listResult.setTotal(Long.valueOf(pages.getTotal()).intValue());
        return listResult;
    }

    /**
     * 根据部门获取人员
     */
    @PostMapping("/getByDept")
    public ListResult<ZcglStaffManagementVO> getByDept(@RequestBody ZcglStaffManagementVO staffFilesVO) {
        List<ZcglStaffManagementVO> staffFilesVOS = staffFilesWrapper.entityToVO(zcglStaffManagementService.getByDept(staffFilesVO.getDepartmentNameId()));
        if (CollectionUtil.isNotEmpty(staffFilesVOS)) {
            for (ZcglStaffManagementVO vo : staffFilesVOS) {
                if ("企业负责人".equals(staffFilesVO.getDepartmentNameId())) {
                    vo.setDepartmentName("企业负责人");
                    vo.setDepartmentNameId(null);
                    vo.setIsLeader(2);
                } else {
                    vo.setIsLeader(1);
                }

                if (StringUtil.isNotBlank(vo.getManagementCategoryId()) && "027002".equals(vo.getManagementCategoryId())) {
                    vo.setIsMiddle(2);
                    vo.setMiddleAverageNumber(new BigDecimal(1));
                } else {
                    vo.setIsMiddle(1);
                }
                vo.setAverageNumber(new BigDecimal(1));
            }
        }
        ListResult<ZcglStaffManagementVO> listResult = new ListResult<>(CommonCode.SUCCESS);
        listResult.setList(staffFilesVOS);
        return listResult;

    }


    /**
     * 生成可以导入的excel文件
     *
     * @return
     */
    @GetMapping("/exportImportFile")
    public ObjResult exportImportFile() {
        PageData pd = new PageData();
        pd.put("key", zcglStaffManagementService.exportImportFile());
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        objResult.setPageData(pd);
        return objResult;
    }

    /**
     * 下载excel文件 并删除
     *
     * @param key
     * @param response
     */
    @GetMapping("/download/{key}")
//    @PassToken
    public void download(@PathVariable String key, HttpServletResponse response) {
        zcglStaffManagementService.download(key, response);
    }

    @GetMapping("/encryptBase64Data")
    public void encryptBase64Data() {
        List<ZcglStaffManagement> staffFilesList = zcglStaffManagementService.list(Wrappers.<ZcglStaffManagement>lambdaQuery().isNotNull(ZcglStaffManagement::getStaffCode));
        for (ZcglStaffManagement staffFiles : staffFilesList) {
            if (StringUtil.isNotBlank(staffFiles.getStaffCode())) {
                staffFiles.setStaffCode(EncryptUtil.encryptBase64(staffFiles.getStaffCode(), BASE64_KEY));
            }
            if (StringUtil.isNotBlank(staffFiles.getDocumentNumber())) {
                staffFiles.setDocumentNumber(EncryptUtil.encryptBase64(staffFiles.getDocumentNumber(), BASE64_KEY));
            }
        }
        zcglStaffManagementService.updateBatchById(staffFilesList);
    }
}
